import json
from itertools import product as itertools_product
from handle.S2Redis import redis_client, sync_data_background
from object.models import Product, Specification, SubSpecification, ProductSpecification,VariantSpecification,ProductVariant
from object.database import db
from handle.logger import logger
from config import Config


def sum_list(product_data,status,stock_map):
    product_list=[]
    for product in product_data:
        if status!="" and status!=None:
            if product["Status"]!=status:
                continue
        product_id = product["ProductID"]
        product_list.append({
            "ProductID": product["ProductID"],
            "Name": product["Name"],
            "Description": product.get("Description", "null"),
            "Price": float(product["Price"]),
            "Currency": product["Currency"],
            "Country": product["Country"],
            "Status": product["Status"],
            "StockQuantity": stock_map.get(product_id, 0),
            "Remarks": product.get("Remarks", "null"),
            "Cover": Config.URL+product.get("Cover", "null")
        })
    return len(product_list)

def get_product_list(request_data,name):
    """
    查询商品列表并返回格式化的数据。
    
    Args:
        redis_client: Redis客户端实例。
    
    Returns:
        list: 商品列表，包含格式化的数据。
    """
    # 获取商品数据和变体数据
    totalSize={}
    page=request_data["page"]
    size=request_data["size"]
    product_data = redis_client.get('product')
    product_variant_data = redis_client.get('productvariant')

    # 如果数据为空，返回空列表
    if not product_data or not product_variant_data:
        return []

    # 将数据从JSON字符串转换为Python对象
    product_data = json.loads(product_data)
    product_variant_data = json.loads(product_variant_data)

    # 创建一个字典，用于映射每个ProductID的库存总量
    stock_map = {}
    for variant in product_variant_data:
        product_id = variant["ProductID"]
        stock = variant["Stock"]
        stock_map[product_id] = stock_map.get(product_id, 0) + stock

    # 生成最终的商品列表
    product_list = []
    
    
    for product in product_data:
        if request_data["status"]!="" and request_data["status"]!=None:
            if product["Status"]!=request_data["status"]:
                continue
        if request_data["IDlist"] != [] and request_data["IDlist"] != None:
            if product["ProductID"] not in request_data["IDlist"]:
                continue
        if name!="" and name!=None:
            if name not in product["Name"]:
                continue
            
        product_id = product["ProductID"]
        product_list.append({
            "ProductID": product["ProductID"],
            "Name": product["Name"],
            "Description": product.get("Description", "null"),
            "Price": float(product["Price"]),
            "Currency": product["Currency"],
            "Country": product["Country"],
            "Status": product["Status"],
            "StockQuantity": stock_map.get(product_id, 0),
            "Remarks": product.get("Remarks", "null"),
            "Cover": Config.URL+product.get("Cover", "null")
        })
    # print(product_list)
    #总页数计算
    totalSize["all"]=len(product_list)
    totalSize["not_listed"]=sum_list(product_data=product_list,status="未上架",stock_map=stock_map)
    totalSize["listed"]=sum_list(product_data=product_list,status="已上架",stock_map=stock_map)
    totalSize["audit"]=sum_list(product_data=product_list,status="待审核",stock_map=stock_map)
    totalSize["not_approved"]=sum_list(product_data=product_list,status="未通过",stock_map=stock_map)
    
    page_count= int(len(product_list)/size)+1 if float(len(product_list)/size)>float(int(len(product_list)/size)) else int(len(product_list)/size)
    
    # 根据页码和每页大小进行分页
    
    start_index = (page - 1) * size
    end_index = start_index + size
    if end_index > len(product_list):
        end_index = len(product_list)
    product_list = product_list[start_index:end_index]
    
    return product_list,page_count,totalSize


def create_product(product_data):
    """
    新建商品并插入相关规格、子规格、变体和变体规格数据。
    
    Args:
        product_data (dict): 商品数据字典。
    """
    try:
        # Step 1: 创建 Product 对象并保存到数据库
        logger.info("开始创建商品...")
        new_product = Product(
            Name=product_data["Name"],
            Description=product_data.get("Description", None),
            Price=float(product_data["Price"]),
            Currency=product_data["Currency"],
            Country=product_data["Country"],
            Cover="upload/img/default.jpg" if (product_data["Cover"] == "" or product_data["Cover"]==None) else product_data["Cover"],
            Status="未上架",
            Remarks=product_data.get("Remarks", None)
        )
        db.session.add(new_product)
        db.session.commit()  # 提交以获取 ProductID

        # 获取生成的 ProductID
        product_id = new_product.ProductID
        logger.info(f"商品创建成功，ProductID={product_id}")

        # Step 2: 遍历 specification 并创建 Specification 和 SubSpecification 对象
        all_subspecifications = []  # 用于生成变体的子规格组合
        for spec_data in product_data.get("Specification", []):
            # 创建 Specification 对象
            new_spec = Specification(
                SpecName=spec_data["SpecName"],
                Remarks=spec_data.get("Remarks", None)
            )
            db.session.add(new_spec)
            db.session.commit()  # 提交以获取 SpecID

            # 获取生成的 SpecID
            spec_id = new_spec.SpecID
            logger.info(f"规格创建成功，SpecID={spec_id}")

            # Step 3: 关联 Product 和 Specification
            product_spec = ProductSpecification(
                ProductID=product_id,
                SpecID=spec_id
            )
            db.session.add(product_spec)

            # Step 4: 遍历 subspecification 并创建 SubSpecification 对象
            subspec_ids = []
            for sub_spec_data in spec_data.get("Subspecification", []):
                new_sub_spec = SubSpecification(
                    SpecID=spec_id,
                    SubSpecName=sub_spec_data["SubSpecName"],
                    Remarks=sub_spec_data.get("Remarks", None)
                )
                db.session.add(new_sub_spec)
                db.session.commit()  # 提交以获取 SubSpecID
                subspec_ids.append(new_sub_spec.SubSpecID)
                logger.info(f"子规格创建成功，SubSpecID={new_sub_spec.SubSpecID}")

            # 保存当前规格的所有子规格 ID
            all_subspecifications.append(subspec_ids)

        # Step 5: 生成产品变体 (ProductVariant) 和变体规格 (VariantSpecification)
        logger.info("开始生成产品变体...")
        for subspec_combination in itertools_product(*all_subspecifications):  # 使用标准库的笛卡尔积
            # 拼接 SKU：ProductID + 子规格ID
            sku = str(product_id) + ''.join(map(lambda x: f"{x:02d}", subspec_combination))  # 固定每个 SubSpecID 长度为 2 位
            # 创建 ProductVariant 对象
            new_variant = ProductVariant(
                ProductID=product_id,
                SKU=sku,
                Price=float(product_data["Price"]),  # 默认使用商品的价格
                Stock=0  # 默认库存为 0，可以后续更新
            )
            db.session.add(new_variant)
            db.session.commit()  # 提交以获取 VariantID

            # 获取生成的 VariantID
            variant_id = new_variant.VariantID
            logger.info(f"变体创建成功，VariantID={variant_id}, SKU={new_variant.SKU}")

            # 创建 VariantSpecification 对象
            for subspec_id in subspec_combination:
                variant_spec = VariantSpecification(
                    VariantID=variant_id,
                    SubSpecID=subspec_id
                )
                db.session.add(variant_spec)
                logger.info(f"变体规格关联创建成功，VariantID={variant_id}, SubSpecID={subspec_id}")

        # Step 6: 提交所有数据
        db.session.commit()
        logger.info(f"商品 {new_product.Name} 创建成功！")
        sync_data_background()
        return True
    except Exception as e:
        db.session.rollback()  # 回滚事务以防止部分插入
        logger.error(f"创建商品时发生错误：{e}")
        raise
        

def update_product(product):
    try:
        up_product = Product.query.filter_by(ProductID=product['ProductID']).all()
        if up_product:
            up_product[0].Name = product['Name']  # 更新产品名称
            up_product[0].Description = product['Description']  # 更新产品描述
            up_product[0].Price = product['Price']  # 更新产品价格
            up_product[0].Currency = product['Currency']  # 更新产品货币
            up_product[0].Country = product['Country']  # 更新产品国家
            up_product[0].Cover = product['Cover']  # 更新产品封面
            up_product[0].Status=product['Status'] #更新商品状态
            up_product[0].Remarks = product['Remarks']  # 更新产品备注
            db.session.commit()  # 提交更改
            try:
                sync_data_background()
                return True
            except Exception as e:
                return False
        
        else:
            return False
    except Exception as e:
        db.session.rollback()  # 回滚事务以防止部分插入
        logger.error(f"创建商品时发生错误：{e}")
        raise

def delete_product(product_id):
    product=True
    product = Product.query.get(product_id)
    if product:
        db.session.delete(product)
        db.session.commit()  # 提交删除操作
        try:
            print("wait")
            
            sync_data_background()
            return True
        except Exception as e:
            return False
    else:
        return False
    
def get_product_by_id(product_id):
    """
    通过商品ID查询商品详细信息，从Redis缓存获取数据，拼接商品信息、规格信息和SKU列表。

    Args:
        product_id (int): 商品ID。

    Returns:
        dict: 商品详细信息，包含规格和SKU列表。
    """
    try:
        # 获取商品基本信息
        product_key = f"product"
        products_data = redis_client.get(product_key)
        if not products_data:
            return {"error": "Product not found in Redis"}

        products = json.loads(products_data)
        
        # 查找指定 product_id 的商品
        product = next((item for item in products if int(item['ProductID']) == int(product_id)), None)
        
        if not product:
            return {"error": "Product not found"}
        
        # 获取规格信息
        product_specifications_key = f"productspecification"
        product_specifications_data = redis_client.get(product_specifications_key)
        product_specifications = json.loads(product_specifications_data) if product_specifications_data else []
        
        # 获取该商品的规格IDs
        spec_ids = [spec['SpecID'] for spec in product_specifications if int(spec['ProductID']) == int(product_id)]
        # logger.error(spec_ids)
        
        # 获取规格详细信息
        specifications = []
        for spec_id in spec_ids:
            spec_key = f"specification"
            specifications_data = redis_client.get(spec_key)
            if specifications_data:
                specifications_list = json.loads(specifications_data)
                spec = next((item for item in specifications_list if int(item['SpecID']) == int(spec_id)), None)
                if spec:
                    # 获取子规格信息
                    subspecifications_key = f"subspecification"
                    subspecifications_data = redis_client.get(subspecifications_key)
                    subspecifications = json.loads(subspecifications_data) if subspecifications_data else []
                    subspec_list = [
                        {"SubSpecID": str(subspec["SubSpecID"]), "SubSpecName": subspec["SubSpecName"]}
                        for subspec in subspecifications if subspec["SpecID"] == spec_id
                    ]
                    specifications.append({
                        "SpecID": str(spec["SpecID"]),
                        "SpecName": spec["SpecName"],
                        "Subspecification": subspec_list
                    })

        # 获取SKU和库存信息
        product_variants_key = f"productvariant"
        product_variants_data = redis_client.get(product_variants_key)
        product_variants = json.loads(product_variants_data) if product_variants_data else []
        sku_list = []
        stock_quantity = 0

        for variant in product_variants:
            if int(variant["ProductID"]) == int(product_id):
                sku_list.append({
                    "SKU": variant["SKU"],
                    "Price": variant["Price"],
                    "Stock": variant["Stock"]
                })
                stock_quantity += variant["Stock"]

        # 构造返回的商品数据
        product_data = {
            "ProductID": product["ProductID"],
            "Name": product["Name"],
            "Description": product["Description"],
            "Price": product["Price"],
            "Currency": product["Currency"],
            "Country": product["Country"],
            "StockQuantity": stock_quantity,
            "Remarks": product["Remarks"],
            "Cover": product["Cover"],
            "Status": product["Status"],
            "Specification": specifications,
            "SKUList": sku_list
        }

        return product_data

    except Exception as e:
        return {"error": f"Error: {str(e)}"}

    
    
    
    
    
    # """
    # 通过商品ID查询商品详细信息。

    # Args:
    #     product_id (int): 商品ID。

    # Returns:
    #     dict: 商品详细信息，包含规格和SKU列表。
    # """
    # try:
    #     # 查询商品基本信息
    #     product = Product.query.filter_by(ProductID=product_id).first()
    #     if not product:
    #         return {"error": "Product not found"}

    #     # 查询规格信息
    #     product_specifications = ProductSpecification.query.filter_by(ProductID=product_id).all()
    #     specifications = []
    #     for product_spec in product_specifications:
    #         spec = Specification.query.filter_by(SpecID=product_spec.SpecID).first()
    #         if not spec:
    #             continue

    #         # 查询子规格
    #         subspecifications = SubSpecification.query.filter_by(SpecID=spec.SpecID).all()
    #         subspec_list = [
    #             {"SubSpecID": str(subspec.SubSpecID), "SubSpecName": subspec.SubSpecName}
    #             for subspec in subspecifications
    #         ]

    #         specifications.append({
    #             "SpecID": str(spec.SpecID),
    #             "SpecName": spec.SpecName,
    #             "Subspecification": subspec_list
    #         })

    #     # 查询SKU列表
    #     variants = ProductVariant.query.filter_by(ProductID=product_id).all()
    #     sku_list = []
    #     stock_quantity = 0
    #     for variant in variants:
    #         # 查询变体规格
    #         variant_specifications = VariantSpecification.query.filter_by(VariantID=variant.VariantID).all()
    #         sku_stock = variant.Stock
    #         stock_quantity += sku_stock

    #         sku_list.append({
    #             "SKU": int(variant.SKU),
    #             "Price": float(variant.Price),
    #             "Stock": sku_stock
    #         })

    #     # 构造返回结果
    #     product_data = {
    #         "ProductID": product.ProductID,
    #         "Name": product.Name,
    #         "Description": product.Description,
    #         "Price": float(product.Price),
    #         "Currency": product.Currency,
    #         "Country": product.Country,
    #         "StockQuantity": stock_quantity,
    #         "Remarks": product.Remarks,
    #         "Cover": product.Cover,
    #         "Specification": specifications,
    #         "SKUList": sku_list
    #     }
    #     return product_data
    # except Exception as e:
    #     return "None"


def update_product_variant(variant):
    try:
        variant_SKU=variant["SKU"]
        up_variant=ProductVariant.query.filter_by(SKU=variant_SKU).all()
        # logger.error(str(up_variant[0].SKU))
        up_variant[0].Stock=variant["Stock"]
        up_variant[0].Price=variant["Price"]
        db.session.commit()
        try:
            sync_data_background()
            return True
        except Exception as e:
            return False
    except Exception as e:
        db.session.rollback()  # 回滚事务以防止部分插入
        logger.error(f"创建商品时发生错误：{e}")
        raise
    

def get_product_specification(product_id):
    # 获取规格信息
    product_specifications_key = f"productspecification"
    product_specifications_data = redis_client.get(product_specifications_key)
    product_specifications = json.loads(product_specifications_data) if product_specifications_data else []
    
    # 获取该商品的规格IDs
    spec_ids = [spec['SpecID'] for spec in product_specifications if int(spec['ProductID']) == int(product_id)]
    # logger.error(spec_ids)
    
    # 获取规格详细信息
    specifications = []
    for spec_id in spec_ids:
        spec_key = f"specification"
        specifications_data = redis_client.get(spec_key)
        if specifications_data:
            specifications_list = json.loads(specifications_data)
            spec = next((item for item in specifications_list if int(item['SpecID']) == int(spec_id)), None)
            if spec:
                specifications.append({
                    "SpecID": str(spec["SpecID"]),
                    "SpecName": spec["SpecName"]
                })
    logger.info(specifications)
    return specifications


def get_product_subspecification(SpecID):
    spec_key = f"specification"
    specifications_data = redis_client.get(spec_key)
    if specifications_data:
        specifications_list = json.loads(specifications_data)
        spec = next((item for item in specifications_list if int(item['SpecID']) == int(SpecID)), None)
        if spec:
            # 获取子规格信息
            subspecifications_key = f"subspecification"
            subspecifications_data = redis_client.get(subspecifications_key)
            subspecifications = json.loads(subspecifications_data) if subspecifications_data else []
            subspec_list = [
                {"SubSpecID": str(subspec["SubSpecID"]), "SubSpecName": subspec["SubSpecName"]}
                for subspec in subspecifications if int(subspec["SpecID"]) == int(SpecID)
            ]
            logger.info(subspec_list)
            return subspec_list
    return []



def update_product_specification(Spec):
    try:
        up_specification=Specification.query.filter_by(SpecID=Spec["SpecID"]).all()
        up_specification[0].SpecName=Spec["SpecName"]
        
        db.session.commit()
        try:
            sync_data_background()
            return True
        except Exception as e:
            return False
    except Exception as e:
        db.session.rollback()
        logger.error(f"更新商品规格时发生错误：{e}")
        raise
    
def update_product_subspecification(SubSpec):
    try:
        up_subspecification=SubSpecification.query.filter_by(SubSpecID=SubSpec["SubSpecID"]).all()
        up_subspecification[0].SubSpecName=SubSpec["SubSpecName"]
        
        db.session.commit()
        try:
            sync_data_background()
            return True
        except Exception as e:
            return False
    except Exception as e:
        db.session.rollback()
        logger.error(f"更新商品规格时发生错误：{e}")
        raise
    
    
def get_product_SKU(product_id):
    # 获取SKU和库存信息
    product_variants_key = f"productvariant"
    product_variants_data = redis_client.get(product_variants_key)
    product_variants = json.loads(product_variants_data) if product_variants_data else []
    sku_list = []

    for variant in product_variants:
        if int(variant["ProductID"]) == int(product_id):
            sku_list.append({
                "SKU": variant["SKU"],
                "Price": variant["Price"],
                "Stock": variant["Stock"]
            })
    return sku_list



def allowed_file(filename):
    """检查文件扩展名是否允许"""
    return '.' in filename and filename.rsplit('.', 1)[1].lower() in Config.ALLOWED_EXTENSIONS
